#include "stdafx.h"
#include "wf_infoarea.h"

#include "pf_snapper.h"



WF_InfoArea::WF_InfoArea(PF_Container& container,
                                     PF_GraphicView& graphicView)
        :PF_PreviewActionInterface("Info Area",
                           container, graphicView) {}


QAction* WF_InfoArea::createGUIAction(LX_Define::ActionType /*type*/, QObject* /*parent*/) {
/*    QAction* action = new QAction(tr("Polygonal Area"),
                                  tr("&Polygonal Area"),
                                  QKeySequence(), NULL); */
    QAction* action = new QAction(tr("Polygonal Area"), NULL);
    //action->zetStatusTip(tr("Measures the area of a polygon"));
    return action;
}


void WF_InfoArea::init(int status) {
    PF_ActionInterface::init(status);

    currentLine = NULL;
    closingLine = NULL;

    //std::cout << "PF_ActionInfoArea::init: " << status << "\n";
}



void WF_InfoArea::trigger() {

    PF_DEBUG->print("PF_ActionInfoArea::trigger()");
    if (ia.isValid()) {
        ia.close();
        ia.calculate();
        double area = ia.getArea();
        double circ = ia.getCircumference();

        PF_DEBUG->print("PF_ActionInfoArea::trigger: area: %f", area);
        PF_DIALOGFACTORY->commandMessage(tr("Area: %1").arg(area));
        PF_DIALOGFACTORY->commandMessage(tr("Circumference: %1").arg(circ));
    }

    ia.reset();

    /*
    if (point1.valid && point2.valid) {
        double dist = point1.distanceTo(point2);
        QString str;
        str.sprintf("%.6f", dist);
        PF_DIALOGFACTORY->commandMessage(tr("Distance: %1").arg(str));
}
    */
}



void WF_InfoArea::mouseMoveEvent(PF_MouseEvent* e) {
    //PF_DEBUG->print("PF_ActionInfoArea::mouseMoveEvent begin");

    if (getStatus()==SetFirstPoint ||
            getStatus()==SetNextPoint) {

        PF_Vector mouse = snapPoint(e);

        switch (getStatus()) {
        case SetFirstPoint:
            break;

        case SetNextPoint:
            if (prev.valid) {
                deletePreview();
                if (currentLine!=NULL) {
                    preview->removeEntity(currentLine);
                    currentLine = NULL;
                }
                if (closingLine!=NULL) {
                    preview->removeEntity(closingLine);
                    closingLine = NULL;
                }

                currentLine = new PF_Line(preview,
                                          PF_LineAttribute(prev,
                                                      mouse));
                preview->addEntity(currentLine);

				if (preview->count()>1) {
                	closingLine = new PF_Line(preview,
                                          PF_LineAttribute(mouse,
                                                      point1));

                	preview->addEntity(closingLine);
				}

                drawPreview();
            }
            break;

        default:
            break;
        }
    }

    //PF_DEBUG->print("PF_ActionInfoArea::mouseMoveEvent end");
}



void WF_InfoArea::mouseReleaseEvent(PF_MouseEvent* e) {
    if (e->button()==Qt::LeftButton) {
        PF_CoordinateEvent ce(snapPoint(e));
        coordinateEvent(&ce);
    } else if (e->button()==Qt::RightButton) {
        //deletePreview();

        // close the polygon (preview)
        if (getStatus()==SetNextPoint && prev.valid) {
            deletePreview();

            if (currentLine!=NULL) {
                preview->removeEntity(currentLine);
                currentLine = NULL;
            }
            if (closingLine!=NULL) {
                preview->removeEntity(closingLine);
                closingLine = NULL;
            }

            currentLine = new PF_Line(preview,
                                      PF_LineAttribute(prev,
                                                  point1));

            preview->addEntity(currentLine);

            drawPreview();
        }

        trigger();
        init(getStatus()-1);
    }
}



void WF_InfoArea::coordinateEvent(PF_CoordinateEvent* e) {
    if (e==NULL) {
        return;
    }

    PF_Vector mouse = e->getCoordinate();

    switch (getStatus()) {
    case SetFirstPoint:
        point1 = mouse;

        deletePreview();

        ia.addPoint(mouse);
        PF_DIALOGFACTORY->commandMessage(tr("Point: %1/%2")
                                         .arg(mouse.x).arg(mouse.y));

        graphicView->moveRelativeZero(point1);
        prev = mouse;

        setStatus(SetNextPoint);
        break;

    case SetNextPoint:
        if (point1.valid) {
            //point2 = mouse;
            /*deletePreview();
            */
            ia.addPoint(mouse);
            PF_DIALOGFACTORY->commandMessage(tr("Point: %1/%2")
                                             .arg(mouse.x).arg(mouse.y));

            currentLine = NULL;

            graphicView->moveRelativeZero(mouse);
            prev = mouse;

            // automatically detect that the polyline is now closed
            if (ia.isClosed()) {
                trigger();
                setStatus(SetFirstPoint);
            }
            //trigger();
            //setStatus(SetFirstPoint);
        }
        break;

    default:
        break;
    }
}


void WF_InfoArea::updateMouseButtonHints() {
    switch (getStatus()) {
    case SetFirstPoint:
        PF_DIALOGFACTORY->updateMouseWidget(
            tr("Specify first point of polygon"),
            tr("Cancel"));
        break;
    case SetNextPoint:
        PF_DIALOGFACTORY->updateMouseWidget(
            tr("Specify next point of polygon"),
            tr("Terminate"));
        break;
    default:
        PF_DIALOGFACTORY->updateMouseWidget("", "");
        break;
    }
}



void WF_InfoArea::updateMouseCursor() {
    graphicView->setMouseCursor(LX_Define::CadCursor);
}



void WF_InfoArea::updateToolBar() {
    switch (getStatus()) {
    case SetFirstPoint:
    case SetNextPoint:
        PF_DIALOGFACTORY->requestToolBar(LX_Define::ToolBarSnap);
        break;
    default:
        PF_DIALOGFACTORY->requestToolBar(LX_Define::ToolBarInfo);
        break;
    }
}


// EOF
